package com.jiguang.Electricvehicle;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;



import java.lang.reflect.Field;

/**
 * @ProjectName: CQMeatSupervision$
 * @Package: com.sk.lib_core.toast$
 * @ClassName: WarpToast$
 * @Author: sk
 * @CreateDate: 2020/3/16$ 14:53$
 * @UpdateUser: sk
 * @UpdateDate: 2020/3/16$ 14:53$
 * @UpdateRemark:
 * @Version: 1.0
 * @Description: android.view.WindowManager$BadTokenException: Unable to add window
 * <p>
 * Toast显示时会有一个Token，这个Token是由WindowManager创建并管理的，重点是这个Token有时间限制，当超过了一个Toast的显示时长（LENGTH_LONG）后，会把这个Token置为无效。所以把Toast延迟显示后，使用的Token就已经过期了。
 * <p>
 * 这个问题发生在7.x系统上，在8.x的系统已经把显示Toast视图的位置添加了try catch捕获，所以如果只需在适配7.x的系统项目才需要解决这个问题。
 */
public class WarpToast {


    private static Field sField_TN;
    private static Field sField_TN_Handler;
    private static Toast mToast;

    static {
        try {
            sField_TN = Toast.class.getDeclaredField("mTN");
            sField_TN.setAccessible(true);
            sField_TN_Handler = sField_TN.getType().getDeclaredField("mHandler");
            sField_TN_Handler.setAccessible(true);
        } catch (Exception e) {
            //soanr
        }
    }

    private WarpToast() {
    }


    public static void show(Context context, CharSequence message, int duration) {
        if (mToast == null) {
            mToast = Toast.makeText(context.getApplicationContext(), message, duration);
            hook(mToast);
        } else {
            mToast.setDuration(duration);
            mToast.setText(message);
        }
        mToast.show();
    }

    public static void show(Context context, int resId, int duration) {
        if (mToast == null) {
            mToast = Toast.makeText(context.getApplicationContext(), resId, duration);
            hook(mToast);
        } else {
            mToast.setDuration(duration);
            mToast.setText(context.getString(resId));
        }
        mToast.show();
    }


    public static Toast createToast(Context context, CharSequence message, int duration) {
        Toast toast = Toast.makeText(context.getApplicationContext(), message, duration);
        hook(toast);
        return toast;
    }


    /**
     * hook
     *
     * @param toast
     */

    private static void hook(Toast toast) {
        try {
            if(sField_TN == null || sField_TN_Handler==null){
                return;
            }
            Object tn = sField_TN.get(toast);
            Handler preHandler = (Handler) sField_TN_Handler.get(tn);
            sField_TN_Handler.set(tn, new WarpHandler(preHandler));
        } catch (Exception e) {
            //soanr
        }
    }


    private static class WarpHandler extends Handler {
        private Handler impl;

        public WarpHandler(Handler impl) {
            this.impl = impl;
        }

        @Override
        public void dispatchMessage(Message msg) {
            try {
                super.dispatchMessage(msg);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void handleMessage(Message msg) {
            try {
                impl.handleMessage(msg);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }


}
